package com.bluesky.jwf.example1.forms;

import java.util.List;

import com.bluesky.javawebbrowser.domain.html.tags.Div;
import com.bluesky.javawebbrowser.domain.html.tags.Tag;
import com.bluesky.jwf.ComponentFactory;
import com.bluesky.jwf.component.Button;
import com.bluesky.jwf.component.CheckBox;
import com.bluesky.jwf.component.Component;
import com.bluesky.jwf.component.DataTable;
import com.bluesky.jwf.component.FileField;
import com.bluesky.jwf.component.HyperLinkButton;
import com.bluesky.jwf.component.Image;
import com.bluesky.jwf.component.RichTextField;
import com.bluesky.jwf.component.dialog.ConfirmDialog;
import com.bluesky.jwf.component.dialog.MessageDialog;
import com.bluesky.jwf.component.event.AbstractEventHandler;
import com.bluesky.jwf.component.event.EventHandler;
import com.bluesky.jwf.component.list.ListItem;
import com.bluesky.jwf.component.list.PaginationListView;
import com.bluesky.jwf.component.select.DropDownList;
import com.bluesky.jwf.component.select.ListBox;
import com.bluesky.jwf.component.select.TextConverter;
import com.bluesky.jwf.component.tree.TreeNodeNavigator;
import com.bluesky.jwf.component.tree.TreeView;
import com.bluesky.jwf.component.window.ClassicalMdiParentWindow;
import com.bluesky.jwf.component.window.ModalResult;
import com.bluesky.jwf.component.window.Window;
import com.bluesky.jwf.example1.domain.Function;
import com.bluesky.jwf.example1.domain.FunctionService;
import com.bluesky.jwf.example1.domain.Person;
import com.bluesky.jwf.example1.domain.PersonService;

public class DemoWindow extends ClassicalMdiParentWindow {

	private TreeView menuTree;

	public DemoWindow() {
		setTitle("JWF Demo");
	}

	@Override
	public void init(String html) {

		super.init(html);

		menuTree = createMenuTree();
		enableMenuItems(false);

		menuBar.removeAllChildren();
		menuBar.addChild(menuTree);

	}

	@Override
	public void onShow() {

		super.onShow();

		invokeFunction("login");
	}

	private TreeView createMenuTree() {
		TreeView tv = (TreeView) ComponentFactory.getInstance()
				.createComponent(TreeView.class.getSimpleName());
		tv.setItemClass(FunctionTreeViewItem.class);
		tv.setNavigator(new TreeNodeNavigator() {

			@Override
			public List getChildren(Object self) {
				Function f = (Function) self;
				return f.getChildren();
			}

			@Override
			public Object getParent(Object self) {
				Function f = (Function) self;
				return f.getParent();
			}

		});
		tv.setModel(FunctionService.getRootFunction());
		tv.dataBind();

		return tv;
	}

	private void enableMenuItems(final boolean loggedIn) {
		TreeNodeNavigator ng = menuTree.getNavigator();
		ng.tranverse(menuTree.getModel(), new TreeNodeNavigator.Tranverser() {
			@Override
			public void process(Object obj) {
				Function f = (Function) obj;
				if (f.getUrl().equals("Login"))
					f.setDisable(loggedIn);
				else
					f.setDisable(!loggedIn);

			}
		});
		menuTree.dataBind();
	}

	/**
	 * wrap any tag with a window box
	 * 
	 * @param content
	 * @return
	 */
	private Window makeWindow(String title, Tag content) {
		Window window = (Window) ComponentFactory.getInstance()
				.createComponent(Window.class.getSimpleName());
		window.getBodyTag().removeAllChildren();
		window.getBodyTag().addChild(content);
		window.setTitle(title);

		return window;
	}

	public void invokeFunction(String s) {
		if (s.equalsIgnoreCase("login")) {
			// create dialog
			final LoginDialog loginDlg = (LoginDialog) ComponentFactory
					.getInstance().createComponent(
							LoginDialog.class.getSimpleName());
			registerDialog(loginDlg);
			loginDlg.setQueryCloseHandler(new AbstractEventHandler() {

				@Override
				public void handle(Component target, Object parameter,
						EventHandler onComplete) {
					// enable all other menu items
					String username = loginDlg.getUsernameField().getText();
					String password = loginDlg.getPasswordField().getText();
					if (username.equals(password))
					{
						if(onComplete!=null)
							onComplete.handle(target, null,null);
							
						enableMenuItems(true);
					}else
						enableMenuItems(false);

				}
			});

		} else if (s.equalsIgnoreCase("select")) {
			addChildWindow(makeWindow("Select", createSelect()));
		} else if (s.equalsIgnoreCase("HyperLinkButton")) {
			addChildWindow(makeWindow("HyperLinkButton",
					createHyperLinkButton()));
		} else if (s.equalsIgnoreCase("RichTextField")) {
			addChildWindow(makeWindow("RichTextField(Html by CKEditor)",
					createRichTextField()));
		} else if (s.equalsIgnoreCase("FileUpload")) {
			addChildWindow(makeWindow("FileUpload", createFileUpload()));
		} else if (s.equalsIgnoreCase("Image")) {
			addChildWindow(makeWindow("Image", createImage()));
		} else if (s.equalsIgnoreCase("ListView")) {
			addChildWindow(makeWindow("ListView", createListView()));
		} else if (s.equalsIgnoreCase("DataTable")) {
			addChildWindow(makeWindow("DataTable", createDataTable()));
		} else if (s.equalsIgnoreCase("CustomDialog")) {
			addChildWindow(makeWindow("CustomDialog", createCustomDialog()));
		} else if (s.equalsIgnoreCase("ModalDialog")) {
			addChildWindow(makeWindow("ModalDialog", createModalDialog()));
		} else {
			showMessage(s + " is invoked");
		}

	}

	private Tag createFileUpload() {
		final FileField ff = (FileField) ComponentFactory.getInstance()
				.createComponent(FileField.class.getSimpleName());

		Button btn = (Button) ComponentFactory.getInstance().createComponent(
				Button.class.getSimpleName());
		btn.setText("upload");
		btn.setClickHandler(new AbstractEventHandler() {

			@Override
			public void handle(Component target, Object parameter) {

				if (!ff.isEmpty()) {
					String s = "you uploaded " + ff.getFileName() + ",size="
							+ ff.getBuffer().length;

					MessageDialog msg = (MessageDialog) ComponentFactory
							.getInstance().createComponent(
									MessageDialog.class.getSimpleName());

					msg.setMessage(s);

					registerDialog(msg);

					// you can save data to db, here just clear it.
					ff.clearBuffer();
				}
			}
		});

		Tag container = new Div();

		container.addChild(ff);
		container.addChild(btn);

		return container;
	}

	private Tag createTreeView() {
		TreeView tv = (TreeView) ComponentFactory.getInstance()
				.createComponent(TreeView.class.getSimpleName());
		tv.setItemClass(PersonTreeViewItem.class);
		tv.setNavigator(new TreeNodeNavigator() {

			@Override
			public List getChildren(Object self) {

				return ((Person) self).getSubordinates();
			}

			@Override
			public Object getParent(Object self) {

				return ((Person) self).getManger();
			}

		});
		tv.setModel(PersonService.getPeople().get(0));
		tv.dataBind();

		Tag container = new Div();

		container.addChild(tv);

		return container;
	}

	/**
	 * actually is a html editor
	 * 
	 * @return
	 */
	private Tag createRichTextField() {
		RichTextField rtf = (RichTextField) ComponentFactory.getInstance()
				.createComponent(RichTextField.class.getSimpleName());

		Tag container = new Div();

		container.addChild(rtf);

		return container;
	}

	private Tag createHyperLinkButton() {
		final HyperLinkButton linkBtn = (HyperLinkButton) ComponentFactory
				.getInstance().createComponent("HyperLinkButton");
		linkBtn.setText("fooo link");
		linkBtn.setClickHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				MessageDialog dialog = (MessageDialog) ComponentFactory
						.getInstance().createComponent("MessageDialog");
				registerDialog(dialog);

				dialog.setMessage("you just clicked the " + linkBtn.getText()
						+ " hyperLinkButton.");

			}
		});
		Tag container = new Div();

		container.addChild(linkBtn);

		return container;
	}

	private Tag createModalDialog() {
		Button btn2 = (Button) ComponentFactory.getInstance().createComponent(
				"Button");

		btn2.setText("open a modal dialog");
		btn2.setClickHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				/*
				 * create a dialog, add it to the root window.
				 */
				final QuestionDialog dialog = (QuestionDialog) ComponentFactory
						.getInstance().createComponent(
								QuestionDialog.class.getSimpleName());
				dialog.setQuestion("What is your name?");

				registerDialog(dialog);

				ModalResult mr = dialog.showModal();

				showMessage("dialog result:" + mr.toString());

			}
		});

		Tag container = new Div();

		container.addChild(btn2);

		return container;
	}

	private Tag createCheckBox() {
		CheckBox checkbox = (CheckBox) ComponentFactory.getInstance()
				.createComponent(
						com.bluesky.jwf.component.CheckBox.class
								.getSimpleName());

		checkbox.setClickHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				CheckBox cb = (CheckBox) target;

				MessageDialog msgDlg = (MessageDialog) ComponentFactory
						.getInstance().createComponent(
								MessageDialog.class.getSimpleName());
				msgDlg
						.setMessage("you just clicked a chockbox, which value is "
								+ (cb.isChecked() ? "checked" : "not checked"));
				registerDialog(msgDlg);
			}
		});

		Tag container = new Div();

		container.addChild(checkbox);

		return container;
	}

	private Tag createCustomDialog() {
		Button btn2 = (Button) ComponentFactory.getInstance().createComponent(
				"Button");

		btn2.setText("open a dialog");
		btn2.setClickHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				/*
				 * create a dialog, add it to the root window.
				 */
				final QuestionDialog dialog = (QuestionDialog) ComponentFactory
						.getInstance().createComponent(
								QuestionDialog.class.getSimpleName());
				dialog.setQuestion("What is your name?");

				registerDialog(dialog);

				dialog.setCloseHandler(new AbstractEventHandler() {
					@Override
					public void handle(Component target, Object parameter) {
						if (dialog.getModalResult() == ModalResult.OK) {
							final MessageDialog messageDialog = (MessageDialog) ComponentFactory
									.getInstance().createComponent(
											"MessageDialog");
							messageDialog.setMessage("Your answer is:"
									+ dialog.getAnswer());
							registerDialog(messageDialog);

						}
					}
				});
			}
		});

		Tag container = new Div();

		container.addChild(btn2);

		return container;
	}

	private Tag createListView() {
		PaginationListView listView = (PaginationListView) ComponentFactory
				.getInstance().createComponent("PeopleList");
		listView.setItemClass(PeopleListItem.class);
		listView.setPageSize(5);

		listView.setModel(PersonService.getPeople());
		listView.dataBind();

		Tag container = new Div();

		container.addChild(listView);

		return container;
	}

	private Tag createImage() {
		final Image image = (Image) ComponentFactory.getInstance()
				.createComponent("Image");
		image.setSource("image/Winter.jpg");
		image.setWidth(50);
		image.setHeight(50);

		Button adjustImageSizeBtn = (Button) ComponentFactory.getInstance()
				.createComponent("Button");

		adjustImageSizeBtn.setText("Adjust Image Size");
		adjustImageSizeBtn.setClickHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {

				final ConfirmDialog dialog = (ConfirmDialog) ComponentFactory
						.getInstance().createComponent("ConfirmDialog");

				dialog.setQuestion("Do you want enlarge the image or not?");

				registerDialog(dialog);

				dialog.setCloseHandler(new AbstractEventHandler() {
					@Override
					public void handle(Component target, Object parameter) {
						if (dialog.getModalResult() == ModalResult.Yes) {
							image.setWidth(image.getWidth() * 2);
							image.setHeight(image.getHeight() * 2);
						} else {
							image.setWidth(image.getWidth() / 2);
							image.setHeight(image.getHeight() / 2);
						}
					}
				});

			}
		});

		Tag container = new Div();
		container.addChild(image);
		container.addChild(adjustImageSizeBtn);

		return container;
	}

	private Tag createDataTable() {
		DataTable dt = (DataTable) ComponentFactory.getInstance()
				.createComponent("DataTable");

		dt.setFieldNames(new String[] { "A", "B", "C", "D" });
		String[][] data = new String[3][4];

		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 4; j++)
				data[i][j] = String.format("%d%d", i, j);
		dt.setData(data);

		dt.DataBind();

		Tag container = new Div();
		container.addChild(dt);

		return container;
	}

	private Tag createSelect() {

		DropDownList dropDownList = (DropDownList) ComponentFactory
				.getInstance().createComponent(
						DropDownList.class.getSimpleName());
		TextConverter tc = new TextConverter() {
			@Override
			public String toText(Object obj) {
				Person p = (Person) obj;
				return p.getName();
			}
		};
		dropDownList.setTextConverter(tc);
		dropDownList.setItems(PersonService.getPeople());
		dropDownList.setSelectedIndex(2);

		dropDownList.setChangeHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				DropDownList ddl = (DropDownList) target;
				Person p = (Person) ddl.getSelectedItem();
				MessageDialog msgDlg = (MessageDialog) ComponentFactory
						.getInstance().createComponent(
								MessageDialog.class.getSimpleName());
				msgDlg.setMessage("you selected:" + p.getName());
				registerDialog(msgDlg);
			}
		});

		ListBox listBox = (ListBox) ComponentFactory.getInstance()
				.createComponent(ListBox.class.getSimpleName());
		tc = new TextConverter() {
			@Override
			public String toText(Object obj) {
				Person p = (Person) obj;
				return p.getName();
			}
		};
		listBox.setTextConverter(tc);
		listBox.setItems(PersonService.getPeople());
		listBox.setSelectedIndices(new int[] { 1, 3, 5 });
		listBox.setSize(5);

		listBox.setChangeHandler(new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				ListBox listBox = (ListBox) target;
				List<Person> people = (List<Person>) listBox.getSelectedItems();
				MessageDialog msgDlg = (MessageDialog) ComponentFactory
						.getInstance().createComponent(
								MessageDialog.class.getSimpleName());

				StringBuilder sb = new StringBuilder();
				for (Person p : people)
					sb.append(p.getName() + ",");

				msgDlg.setMessage("you selected:" + sb.toString());
				registerDialog(msgDlg);
			}
		});

		Tag container = new Div();
		container.addChild(dropDownList);
		container.addChild(listBox);
		return container;
	}

}
